package com.web.exiaodao.business.service.impl;

import com.web.exiaodao.business.entity.FestivalRemind;
import com.web.exiaodao.business.repository.FestivalRemindRepository;
import com.web.exiaodao.business.service.FestivalRemindService;
import com.web.webstart.base.constant.XaConstant;
import com.web.webstart.base.exception.BusinessException;
import com.web.webstart.base.service.impl.BaseService;
import com.web.webstart.base.util.DateUtils;
import com.web.webstart.base.util.XaUtil;
import com.web.webstart.base.util.jpa.DynamicSpecifications;
import com.web.webstart.base.util.jpa.SearchFilter;
import com.web.webstart.base.util.jpa.SearchFilter.Operator;
import com.web.webstart.base.util.jpush.PushMessgeUtil;
import com.web.webstart.base.util.lunarSolarCalendarConverter.LunarSolarConverter;
import com.web.webstart.base.util.result.XaResult;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.util.*;

import static com.web.webstart.base.util.lunarSolarCalendarConverter.LunarSolarConverter.Lunar;
import static com.web.webstart.base.util.lunarSolarCalendarConverter.LunarSolarConverter.Solar;

@Service("FestivalRemindService")
@Transactional(readOnly = false)
public class FestivalRemindServiceImpl extends BaseService<FestivalRemind> implements FestivalRemindService {

    static final Logger logger = Logger.getLogger(FestivalRemindServiceImpl.class);

	@Autowired
	private FestivalRemindRepository festivalRemindRepository;
	
	/**
	 * 查询单条FestivalRemind信息
	 * //@param tId
	 * @return 返回单个FestivalRemind对象
	 * @throws BusinessException
	 */
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public XaResult<FestivalRemind> findOne(Long modelId) throws BusinessException {
		FestivalRemind obj = new FestivalRemind();
		if(modelId != 0){
			obj = festivalRemindRepository.findByIdAndStatusNot(modelId,XaConstant.Status.delete);
		}
		XaResult<FestivalRemind> xr = new XaResult<FestivalRemind>();
		if (XaUtil.isNotEmpty(obj)) {
			xr.setObject(obj);
		} else {
			throw new BusinessException(XaConstant.Message.object_not_find);
		}
		return xr;
	}

	/**
	 * 分页查询状态非status的FestivalRemind数据
	 * @param status
	 * @param filterParams
	 * @param pageable
	 * @return 返回对象FestivalRemind集合
	 * @throws BusinessException
	 */
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public XaResult<Page<FestivalRemind>> findListNEStatusByFilter(
			Integer status, Map<String, Object> filterParams, Pageable pageable) throws BusinessException {
		Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
		if(status == null){// 默认显示非删除的所有数据
			status = XaConstant.Status.delete;
		}
		filters.put("status", new SearchFilter("status", Operator.NE, status));
		Page<FestivalRemind> page = festivalRemindRepository.findAll(DynamicSpecifications
				.bySearchFilter(filters.values(), FestivalRemind.class), pageable);
		XaResult<Page<FestivalRemind>> xr = new XaResult<Page<FestivalRemind>>();
		xr.setObject(page);
		return xr;
	}

	/**
	 * 分页查询状态status的FestivalRemind数据
	 * @param status
	 * @param filterParams
	 * @param pageable
	 * @return 返回对象FestivalRemind集合
	 * @throws BusinessException
	 */
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public XaResult<Page<FestivalRemind>> findListEQStatusByFilter(
			Integer status, Map<String, Object> filterParams, Pageable pageable) throws BusinessException {
		Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
		if(status == null){// 默认显示正常数据
			status = XaConstant.Status.valid;
		}
		filters.put("status", new SearchFilter("status", Operator.EQ, status));
		Page<FestivalRemind> page = festivalRemindRepository.findAll(DynamicSpecifications
				.bySearchFilter(filters.values(), FestivalRemind.class), pageable);
		XaResult<Page<FestivalRemind>> xr = new XaResult<Page<FestivalRemind>>();
		xr.setObject(page);
		return xr;
	}

	/**
	 * 保存FestivalRemind信息
	 * @param model
	 * @return
	 * @throws BusinessException
	 */
	@Transactional(rollbackFor = Exception.class)
	public XaResult<FestivalRemind> saveOrUpdate(FestivalRemind model) throws BusinessException {
		FestivalRemind obj = null;
		if(XaUtil.isNotEmpty(model.getId())){
			obj = festivalRemindRepository.findOne(model.getId());
		}else{
			obj = new FestivalRemind();
		}
		obj.setName(model.getName());
		obj.setCellphone(model.getCellphone());
		obj.setFestivalDate(model.getFestivalDate());
		obj.setIsLunarCalendar(model.getIsLunarCalendar());
		obj.setDaysDiff(model.getDaysDiff());
		obj.setType(model.getType());
		obj.setUserId(model.getUserId());
		obj = festivalRemindRepository.save(obj);
		XaResult<FestivalRemind> xr = new XaResult<FestivalRemind>();
		xr.setObject(obj);
		return xr;
	}

	/**
	 * 修改FestivalRemind状态，可一次修改多条   3删除  -1锁定  1正常
	 * //@param userId
	 * @param modelIds
	 * @param status
	 * @return 返回FestivalRemind对象
	 * @throws BusinessException
	 */
	@Transactional(rollbackFor = Exception.class)
	public XaResult<FestivalRemind> multiOperate(
			String modelIds,Integer status) throws BusinessException {
		XaResult<FestivalRemind> xr = new XaResult<FestivalRemind>();
		if(status == null){
			status = XaConstant.Status.delete;
		}
		if(modelIds != null){
			String[] ids = modelIds.split(",");
			for(String id : ids){
				FestivalRemind obj = festivalRemindRepository.findByIdAndStatusNot(Long.parseLong(id),status);
				if (XaUtil.isNotEmpty(obj)) {
					obj.setStatus(status);
					obj = festivalRemindRepository.save(obj);
				} else {
					throw new BusinessException(XaConstant.Message.object_not_find);
				}
			}
		}
		return xr;
	}

	/**
	 * @Description: 查询进行提醒(短信or推送)
	 * 生日当天；提前1，7，days_diff天进行提示；
	 * @author duandazhi
	 * @date 2016/10/31 下午1:26
	 */
	@Override
	public void queryFestivalRemind() throws Exception {
        //-- 1:先把农历日期转成阳历
        //---1-1查询所有的该提示的数据(阴历的,没有提示过的)
        String selectRemindlSql = "SELECT * FROM tb_xa_festivalremind WHERE status <> 3 AND is_lunar_calendar AND DATEDIFF(festival_date, CURDATE()) <= days_diff";
        List<FestivalRemind> selectRemdinds = this.query(selectRemindlSql , FestivalRemind.class);
        //---1-2更新日期数据
        for (int i = 0; selectRemdinds != null && i < selectRemdinds.size(); i++) {
            String updateDateSql = "UPDATE tb_xa_festivalremind SET solar_festival_date = ? WHERE id = ?";
            FestivalRemind entity = selectRemdinds.get(i);
            String festivalDate   = entity.getFestivalDate();//阴历日期
            festivalDate = new GregorianCalendar().get(Calendar.YEAR) + "" + festivalDate.substring(4);
            String solarDateStr = null;
            try {
                solarDateStr = lunnarToSolar(festivalDate);
                Date date = DateUtils.formatStr(solarDateStr, DateUtils.YYYYMMDD);
                if (date == null) {
                    throw new ParseException("", 0);
                }
                //在加上
                List<Object> params = new ArrayList<>();
                params.add(solarDateStr);
                params.add(selectRemdinds.get(i).getId());
                int count = this.update(updateDateSql, params);
                System.out.println();
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("", e);
            }
        }

        List<FestivalRemind> festivalRemindList = new ArrayList<>();
        //-- 2-1生日提醒(阳历)
        String remindsSql_solar =
                "-- 提前0，1，7，days_diff天进行提示\n" +
						"SELECT wrapTb.* FROM (SELECT tb.*, DATEDIFF(\n" +
						"                                DATE_ADD(DATE_FORMAT(festival_date,'%Y-%m-%d'), INTERVAL ((YEAR(CURDATE()) - YEAR(DATE_FORMAT(festival_date,'%Y-%m-%d')))) YEAR)\n" +
						"                                , CURDATE()) as mydiff\n" +
						"                    FROM tb_xa_festivalremind tb)\n" +
						"                   as wrapTb\n" +
						"WHERE ( wrapTb.mydiff = 0 or wrapTb.mydiff = 1 OR wrapTb.mydiff = 7)\n" +  //提前0，1，7，days_diff天进行提示
						"      AND wrapTb.status <> 3 AND not wrapTb.is_lunar_calendar ";
        List<FestivalRemind> reminds1 =  this.query(remindsSql_solar, FestivalRemind.class);
        if (XaUtil.isNotEmpty(reminds1)) festivalRemindList.addAll(reminds1);
        //-- 2-2生日提醒(阴历)
        String remindsSql_lunnar =
             "SELECT wrapTb.* FROM (SELECT *,\n" +
					 "                  DATEDIFF(solar_festival_date, CURDATE()) as myDayDiff FROM\n" +
					 "              tb_xa_festivalremind) wrapTb\n" +
					 "WHERE ( wrapTb.myDayDiff = 0 || wrapTb.myDayDiff = 1 || wrapTb.myDayDiff = 7)\n" +   //提前0，1，7，days_diff天进行提示
					 "      AND wrapTb.status <> 3 AND wrapTb.is_lunar_calendar ";
        List<FestivalRemind> reminds2 =  this.query(remindsSql_lunnar, FestivalRemind.class);
        if (XaUtil.isNotEmpty(reminds2)) festivalRemindList.addAll(reminds2);

        //--3:遍历日期,进行推送
        for (int j = 0; j < festivalRemindList.size(); ++j) {
            FestivalRemind festvialRemind = festivalRemindList.get(j);
            String mobile = festvialRemind.getCellphone();
            PushMessgeUtil.pushMessage(festvialRemind.getName() + (festvialRemind.getType().intValue() == 1 ? "生日马上到了" : ""), Arrays.asList(mobile));
        }
	}



    /**
     * 阴历日期变成阳历
     * @param lunnarStr 阴历的日期 yyyy-mm-dd
     * @return yyyy-mm-dd
     */
	private  static  String lunnarToSolar(String lunnarStr) {
        Date date =  DateUtils.formatStr(lunnarStr, DateUtils.YYYYMMDD);
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);

        Lunar lunar = new Lunar();//阴历的
        lunar.lunarYear  = calendar.get(Calendar.YEAR);
        lunar.lunarMonth = calendar.get(Calendar.MONTH) + 1;
        lunar.lunarDay   = calendar.get(Calendar.DAY_OF_MONTH);
        Solar solar = LunarSolarConverter.LunarToSolar(lunar);//阴历的->阳历的

        String solarStr = solar.solarYear + "-" + solar.solarMonth + "-" + solar.solarDay;
        return solarStr;
    }
}
